package gameobjects;

import interfaces.Collidable;
import interfaces.CollisionHandler;
import interfaces.Movable;
import interfaces.Visible;
import java.awt.Graphics;
import resources.Sound;
import resources.Sprite;
import tools.Bounds;
import tools.CollisionGrid;
import tools.Direction;
import abstracts.Level;
import abstracts.Monster;

public class Fireball implements Visible, Movable, CollisionHandler {
    private final Level LEVEL;

    private Bounds bounds;
    private Direction dir;
    private double speed;

    private double frameIndex;
    private double frameSpeed;
    private Sprite sprite;

    Fireball(double x, double y, Direction dir, Level level) {
        bounds = new Bounds(x - 4, y - 4, 8, 8);

        this.dir = dir;

        // Not very good style but it works and takes much less space
        // than a
        // switch statement ;-)
        sprite = Sprite.valueOf("FIREBALL_" + dir.toString());

        speed = 4;

        frameIndex = 0;
        frameSpeed = 0.125;

        LEVEL = level;
    }

    @Override
    public void move() {
        // Move
        LEVEL.getCollisionGrid().removeCollidable(this);
        bounds.x += dir.X * speed;
        bounds.y += dir.Y * speed;
        LEVEL.getCollisionGrid().addCollidable(this);

        if (LEVEL.getCollisionGrid().hasSolid(getBounds())) {
            Sound.FIREBALL_DEATH.play();
            LEVEL.remove(this);
        }
    }

    @Override
    public void draw(Graphics g) {
        sprite.drawAnchored(g, (int) frameIndex, bounds);

        frameIndex += frameSpeed;
        while (frameIndex >= sprite.getFrameCount()) {
            frameIndex -= sprite.getFrameCount();
        }
    }

    @Override
    public double getDepth() {
        return bounds.getMaxY();
    }

    @Override
    public Bounds getBounds() {
        return bounds;
    }

    @Override
    public void collide(CollisionGrid cg) {
        for (Collidable other : cg.getCollidables(bounds)) {
            if (other instanceof Monster) {
                LEVEL.remove(this);
                ((Monster) other).hurt();
            }
        }
    }
}
